package com.tjmc.tiomsresource.service.impl;

/**
 * @author Luc
 * @version 1.0
 * @date 2020-05-23 21:41
 */

import com.google.common.collect.Lists;
import com.tjmc.tiomscore.dao.TranPtnHwSuperMapper;
import com.tjmc.tiomsresource.parser.AbstractParser;
import com.tjmc.tiomsresource.thread.TranPtnHwPreThread;
import com.tjmc.tiomsresource.utils.Constants;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @param: D, Dao   M, Model    P, Parser
 * @return:
 * @date: 2020/5/23
 */
@PropertySource({"classpath:nce.properties"})
public abstract class CMSuperServiceImpl<T> {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

//    protected static final int BATCH_SPLIT_CAPACITY = 3000;

    @Value("${omc.parse.sync}")
    private int parseSync;

    @Autowired
    private TranPtnHwPreThread tranPtnHwPreThread;

    public abstract TranPtnHwSuperMapper<T> getMapper();

    public abstract AbstractParser<T> getParser();


    public void clearTranPtnHwTable() {
        getMapper().truncateTable();
    }

    public void batchAddTranPtnHwData(List<T> mList) {
        List<List<T>> lists = Lists.partition(mList, Constants.BATCH_SPLIT_SIZE);
        int i = 0;
        for(List<T> list : lists) {
            logger.info("插入数据, i=" + i);
            try {
                getMapper().insertBatch(list);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
            i += list.size();
        }
        logger.info("插入数据完成, i=" + i);
    }

    public boolean saveTranPtnHwDataToDB(List<File> xmlFiles, String TableId) {
        if(null == xmlFiles || xmlFiles.size() == 0) {
            logger.info("同步 " + TableId +" 数据错误, 解压缩文件为空");
            return false;
        }
        List<T> mList = new ArrayList<>();
        for(File xmlFile : xmlFiles) {
            if(xmlFile.getName().startsWith("CM-SPN-" + TableId) && xmlFile.getName().endsWith(".xml")) {
                List<T> parseResult = new ArrayList<>();
                logger.info("发现 " + TableId +" 原始采集文件, 开始解析：" + xmlFile.getAbsolutePath());
                try {
                    List<Element> objectElements = getParser().parseXML(xmlFile.getAbsolutePath());
                    logger.info("发现 " + TableId +" 原始采集文件, 解析XML Elements 共：" + objectElements.size());
//                    if(parseSync == 0) {
//                        //多线程解析
//                        List<List<Element>> objectElementsList = Lists.partition(objectElements, Constants.BATCH_SPLIT_SIZE);
//                        List<CompletableFuture<List<T>>> results = new ArrayList<>();
//                        for(List<Element> list : objectElementsList) {
//                            //多线程
//                            CompletableFuture<List<T>> result = tranPtnHwPreThread.syncParseXML(getParser(), list);
//                            result.whenComplete((objects, throwable) -> parseResult.addAll(objects));
//                            results.add(result);
//                        }
//                        CompletableFuture.allOf(results.toArray(new CompletableFuture[results.size()])).join();
//                    } else if(parseSync == 1) {
                        //单线程解析
                        parseResult.addAll(getParser().parseXML(objectElements));
//                    }

                    mList.addAll(parseResult);
                    parseResult.clear();
                } catch (DocumentException e) {
                    logger.info(TableId + " 原始采集文件解析错误：" + xmlFile.getAbsolutePath());
                    e.printStackTrace();
                    continue;
                }
                logger.info(TableId +" 原始采集文件，解析完成, 解析结果：" + mList.size());
            }
        }
        if(mList.size() > 0) {
            clearTranPtnHwTable();
            batchAddTranPtnHwData(mList);
        }
        mList.clear();
        System.gc();
        return true;
    }
}
